package raft

import (
	"encoding/json"
	"fmt"
	"time"
)

const WORKER_TIKTOK = "WORKER_TIKTOK"

// CommandExecRet
// 命令执行通用返回结构
type CommandExecRet struct {
	Status   int64  `json:"status"` //0-未执行，1-成功，-1-失败，2-执行中
	Progress string `json:"progress"`
	Data     string `json:"data"`
	Msg      string `json:"msg"`
}

type CommandEntry struct {
	Name       string            `json:"name"`
	Params     map[string]string `json:"params"`
	ExecStatus int64             `json:"execStatus"` //0，未执行，1，成功，-1，失败
	ExecMsg    string            `json:"execMsg"`    //执行信息
}

type ExecCommandWebSocketMsg struct {
	NanoId     string
	QueueIndex int
	ExecStatus int
	ExecMsg    string
}

// InitBuiltinCommand
// 初始化内部命令
func (r *Raft) InitBuiltinCommand() {
	r.Commands = make(map[string]func(map[string]string) CommandExecRet)
	r.RegisterCommands(WORKER_TIKTOK, "accept tiktok message from a worker", r.AcceptTikTokFromWorker)
	r.Commands[HELP] = r.Help

}

// RegisterCommands
// 命令注册
func (r *Raft) RegisterCommands(name string, description string, method func(args map[string]string) CommandExecRet) {
	if r.Commands == nil {
		r.Commands = make(map[string]func(args map[string]string) CommandExecRet)
	}
	if r.CommandsDes == nil {
		r.CommandsDes = make(map[string]string)
	}
	r.Commands[name] = method
	r.CommandsDes[name] = description
}

// RegisterExCommands
// 注册外部命令，除了Raft内置的命令，还有外部命令
func (r *Raft) RegisterExCommands(name string, description string, method func(args map[string]string) CommandExecRet) {
	//TODO  检测注册命令的合法性
	r.Commands[name] = method
	r.CommandsDes[name] = description
}

//func (r *Raft) CreateCommandProgress(cmdGroupKey string, ces []CommandEntry) error {
//
//}

// RegisterWorker
// 对应指令 "WORKER_REGISTER" 的具体方法
func (r *Raft) AcceptTikTokFromWorker(args map[string]string) CommandExecRet {
	ret := CommandExecRet{
		Status: 0,
		Msg:    "",
	}
	workerInfo := WorkerInfo{}
	unmarshalErr := json.Unmarshal([]byte(args["workerInfo"]), &workerInfo)
	if unmarshalErr != nil {
		ret.Status = -1
		ret.Msg = fmt.Sprintf("can not unmarshal params to worker info:%s", unmarshalErr.Error())
		return ret
	}
	workerInfo.TickTok = time.Now()
	r.Workers[args["ip"]] = workerInfo
	ret.Status = 1
	ret.Msg = fmt.Sprintf("accept tiktok from %s success")
	return ret
}

func (r *Raft) AppendCommandQueue(id string, ces []CommandEntry) {
	r.Mutex.Lock()
	//commandNum := len(r.CommandQueues)
	//if commandNum > 100 {
	//	for key, queue := range r.CommandQueues {
	//		shouldDelete := true
	//		for _, ce := range queue {
	//			if ce.ExecStatus == 0 {
	//				shouldDelete = false
	//				break
	//			}
	//		}
	//		if shouldDelete {
	//			//TODO 此处需要优化，不仅仅是删除，还要保存下来
	//			delete(r.CommandQueues, key)
	//		}
	//	}
	//}
	//for _, ce := range ces {
	//	r.CommandQueues[id] = append(r.CommandQueues[id], ce)
	//}
	r.Mutex.Unlock()
}

// Help
// 帮助文档
func (r *Raft) Help(args map[string]string) CommandExecRet {
	ret := CommandExecRet{
		Status: 0,
		Msg:    "",
	}
	//for k, c := range r.Commands {
	//	ret.Msg = ret.Msg + k + "----" + c.Usage + "\n"
	//}
	//ret.Success = true
	return ret
}
